home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume11 / id / part03 < prev    next >
Encoding:
Internet Message Format  |  1987-09-25  |  43.8 KB

  1. Subject:  v11i080:  C cross-reference database system, Part03/03
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rs@uunet.UU.NET
  5.  
  6. Submitted-by: sun!suneast!kumquat!gmcgary (Greg Mcgary - Sun ECD Software)
  7. Posting-number: Volume 11, Issue 80
  8. Archive-name: id/Part03
  9.  
  10.  
  11.  
  12. #! /bin/sh
  13. # This is a shell archive, meaning:
  14. # 1. Remove everything above the #! /bin/sh line.
  15. # 2. Save the resulting text in a file.
  16. # 3. Execute the file with /bin/sh (not csh) to create the files:
  17. #    mkid.c
  18. #    numtst.c
  19. #    opensrc.c
  20. #    paths.c
  21. #    scan-asm.c
  22. #    scan-c.c
  23. #    stoi.c
  24. #    tty.c
  25. #    uerror.c
  26. #    wmatch.c
  27. export PATH; PATH=/bin:$PATH
  28. echo shar: extracting "'mkid.c'" '(17095 characters)'
  29. sed 's/^X//' << \SHAR_EOF > 'mkid.c'
  30. Xstatic char copyright[] = "@(#)Copyright (c) 1986, Greg McGary";
  31. Xstatic char sccsid[] = "@(#)mkid.c    1.4 86/11/06";
  32. X
  33. X#include    <bool.h>
  34. X#include    <sys/types.h>
  35. X#include    <sys/stat.h>
  36. X#include    <stdio.h>
  37. X#include    <string.h>
  38. X#include    <ctype.h>
  39. X#include    <id.h>
  40. X#include    <bitops.h>
  41. X#include    <errno.h>
  42. X#include    <extern.h>
  43. X
  44. Xint idnHashCmp();
  45. Xint idnQsortCmp();
  46. Xint round2();
  47. Xstruct idname *newIdName();
  48. Xvoid extractId();
  49. Xvoid fileIdArgs();
  50. Xvoid initHashTable();
  51. Xvoid oldIdArgs();
  52. Xvoid rehash();
  53. Xvoid updateID();
  54. Xvoid writeID();
  55. X
  56. Xlong    NameCount;        /* Count of names in database */
  57. Xlong    NumberCount;        /* Count of numbers in database */
  58. Xlong    StringCount;        /* Count of strings in database */
  59. Xlong    SoloCount;        /* Count of identifiers that occur only once */
  60. X
  61. Xlong    HashSize;        /* Total Slots in hash table */
  62. Xlong    HashMaxLoad;        /* Maximum loading of hash table */
  63. Xlong    HashFill;        /* Number of keys inserted in table */
  64. Xlong    HashProbes;        /* Total number of probes */
  65. Xlong    HashSearches;        /* Total number of searches */
  66. Xstruct idname    **HashTable;    /* Vector of idname pointers */
  67. X
  68. Xbool    Verbose = FALSE;
  69. X
  70. Xint    ArgsCount = 0;        /* Count of args to save */
  71. Xint    ScanCount = 0;        /* Count of files to scan */
  72. Xint    PathCount = 0;        /* Count of files covered in database */
  73. Xint    BitArraySize;        /* Size of bit array slice (per name) */
  74. X
  75. X
  76. Xchar    *MyName;
  77. Xstatic void
  78. Xusage()
  79. X{
  80. X    fprintf(stderr, "Usage: %s [-f<idfile>] [-s<dir>] [-r<dir>] [(+|-)l[<lang>]] [-v] [(+|-)S<scanarg>] [-a<argfile>] [-] [-u] [files...]\n", MyName);
  81. X    exit(1);
  82. X}
  83. Xmain(argc, argv)
  84. X    int        argc;
  85. X    char        **argv;
  86. X{
  87. X    char        *arg;
  88. X    int        op;
  89. X    FILE        *argFILE = NULL;
  90. X    char        *idFile = IDFILE;
  91. X    char        *rcsDir = NULL;
  92. X    char        *sccsDir = NULL;
  93. X    struct idarg    *idArgs, *idArgHead;
  94. X    bool        keepLang = FALSE;
  95. X    int        argsFrom = 0;
  96. X#define    AF_CMDLINE    0x1    /* file args came on command line */
  97. X#define    AF_FILE        0x2    /* file args came from a file (-f<file>) */
  98. X#define    AF_IDFILE    0x4    /* file args came from an old ID file (-u) */
  99. X#define    AF_QUERY    0x8    /* no file args necessary: usage query */
  100. X
  101. X    MyName = basename(GETARG(argc, argv));
  102. X#ifdef ERRLINEBUF
  103. X    setlinebuf(stderr);
  104. X#endif
  105. X
  106. X    idArgs = idArgHead = NEW(struct idarg);
  107. X
  108. X    /*
  109. X        Process some arguments, and snarf-up some
  110. X        others for processing later.
  111. X    */
  112. X    while (argc) {
  113. X        arg = GETARG(argc, argv);
  114. X        if (*arg != '-' && *arg != '+') {
  115. X            argsFrom |= AF_CMDLINE;
  116. X            idArgs->ida_arg = arg;
  117. X            idArgs->ida_flags = IDA_SCAN|IDA_PATH;
  118. X            idArgs->ida_index = postIncr(&PathCount);
  119. X            ScanCount++;
  120. X            idArgs = (idArgs->ida_next = NEW(struct idarg));
  121. X            continue;
  122. X        }
  123. X        op = *arg++;
  124. X        switch (*arg++)
  125. X        {
  126. X        case 'u':
  127. X            argsFrom |= AF_IDFILE;
  128. X            oldIdArgs(idFile, &idArgs);
  129. X            break;
  130. X        case '\0':
  131. X            argsFrom |= AF_FILE;
  132. X            fileIdArgs(stdin, &idArgs);
  133. X            break;
  134. X        case 'a':
  135. X            if ((argFILE = fopen(arg, "r")) == NULL) {
  136. X                filerr("open", arg);
  137. X                exit(1);
  138. X            }
  139. X            argsFrom |= AF_FILE;
  140. X            fileIdArgs(argFILE, &idArgs);
  141. X            break;
  142. X        case 'f':
  143. X            idFile = arg;
  144. X            break;
  145. X        case 'v':
  146. X            Verbose = TRUE;
  147. X            break;
  148. X        case 'S':
  149. X            if (strchr(&arg[-2], '?')) {
  150. X                setScanArgs(op, arg);
  151. X                argsFrom |= AF_QUERY;
  152. X            }
  153. X            /*FALLTHROUGH*/
  154. X        case 'l':
  155. X        case 's':
  156. X        case 'r':
  157. X            idArgs->ida_arg = &arg[-2];
  158. X            idArgs->ida_index = -1;
  159. X            idArgs->ida_flags = IDA_ARG;
  160. X            idArgs = (idArgs->ida_next = NEW(struct idarg));
  161. X            ArgsCount++;
  162. X            break;
  163. X        default:
  164. X            usage();
  165. X        }
  166. X    }
  167. X
  168. X    if (argsFrom & AF_QUERY)
  169. X        exit(0);
  170. X    /*
  171. X        File args should only come from one place.  Ding the
  172. X        user if arguments came from multiple places, or if none
  173. X        were supplied at all.
  174. X    */
  175. X    switch (argsFrom)
  176. X    {
  177. X    case AF_CMDLINE:
  178. X    case AF_FILE:
  179. X    case AF_IDFILE:
  180. X        if (PathCount > 0)
  181. X            break;
  182. X        /*FALLTHROUGH*/
  183. X    case 0:
  184. X        fprintf(stderr, "%s: Use -u, -f<file>, or cmd-line for file args!\n", MyName);
  185. X        usage();
  186. X    default:
  187. X        fprintf(stderr, "%s: Use only one of: -u, -f<file>, or cmd-line for file args!\n", MyName);
  188. X        usage();
  189. X    }
  190. X
  191. X    if (ScanCount == 0)
  192. X        exit(0);
  193. X
  194. X    BitArraySize = (PathCount + 7) >> 3;
  195. X    initHashTable(ScanCount);
  196. X
  197. X    if (access(idFile, 06) < 0
  198. X    && (errno != ENOENT || access(dirname(idFile), 06) < 0)) {
  199. X        filerr("modify", idFile);
  200. X        exit(1);
  201. X    }
  202. X
  203. X    for (idArgs = idArgHead; idArgs->ida_next; idArgs = idArgs->ida_next) {
  204. X        char        *(*scanner)();
  205. X        FILE        *srcFILE;
  206. X        char        *arg, *lang, *suff;
  207. X
  208. X        arg = idArgs->ida_arg;
  209. X        if (idArgs->ida_flags & IDA_ARG) {
  210. X            op = *arg++;
  211. X            switch (*arg++)
  212. X            {
  213. X            case 'l':
  214. X                if (*arg == '\0') {
  215. X                    keepLang = FALSE;
  216. X                    lang = NULL;
  217. X                    break;
  218. X                }
  219. X                if (op == '+')
  220. X                    keepLang = TRUE;
  221. X                lang = arg;
  222. X                break;
  223. X            case 's':
  224. X                sccsDir = arg;
  225. X                break;
  226. X            case 'r':
  227. X                rcsDir = arg;
  228. X                break;
  229. X            case 'S':
  230. X                setScanArgs(op, strsav(arg));
  231. X                break;
  232. X            default:
  233. X                usage();
  234. X            }
  235. X            continue;
  236. X        }
  237. X        if (!(idArgs->ida_flags & IDA_SCAN))
  238. X            goto skip;
  239. X        if (lang == NULL) {
  240. X            if ((suff = strrchr(arg, '.')) == NULL)
  241. X                suff = "";
  242. X            if ((lang = getLanguage(suff)) == NULL) {
  243. X                fprintf(stderr, "%s: No language assigned to suffix: `%s'\n", MyName, suff);
  244. X                goto skip;
  245. X            }
  246. X        }
  247. X        if ((scanner = getScanner(lang)) == NULL) {
  248. X            fprintf(stderr, "%s: No scanner for language: `%s'\n", MyName, lang);
  249. X            goto skip;
  250. X        }
  251. X        if ((srcFILE = openSrcFILE(arg, sccsDir, rcsDir)) == NULL)
  252. X            goto skip;
  253. X        if (Verbose)
  254. X            fprintf(stderr, "%s: %s\n", lang, arg);
  255. X        extractId(scanner, srcFILE, idArgs->ida_index);
  256. X        fclose(srcFILE);
  257. X    skip:
  258. X        if (!keepLang)
  259. X            lang = NULL;
  260. X    }
  261. X
  262. X    if (HashFill == 0)
  263. X        exit(0);
  264. X
  265. X    if (Verbose)
  266. X        fprintf(stderr, "Compressing Hash Table...\n");
  267. X    hashCompress(HashTable, HashSize);
  268. X    if (Verbose)
  269. X        fprintf(stderr, "Sorting Hash Table...\n");
  270. X    qsort(HashTable, HashFill, sizeof(struct idname *), idnQsortCmp);
  271. X
  272. X    if (argsFrom == AF_IDFILE) {
  273. X        if (Verbose)
  274. X            fprintf(stderr, "Merging Tables...\n");
  275. X        updateID(idFile, idArgHead);
  276. X    }
  277. X
  278. X    if (Verbose)
  279. X        fprintf(stderr, "Writing `%s'...\n", idFile);
  280. X    writeID(idFile, idArgHead);
  281. X
  282. X    if (Verbose) {
  283. X        float loadFactor = (float)HashFill / (float)HashSize;
  284. X        float aveProbes = (float)HashProbes / (float)HashSearches;
  285. X        float aveOccur = (float)HashSearches / (float)HashFill;
  286. X        fprintf(stderr, "Names: %ld, ", NameCount);
  287. X        fprintf(stderr, "Numbers: %ld, ", NumberCount);
  288. X        fprintf(stderr, "Strings: %ld, ", StringCount);
  289. X        fprintf(stderr, "Solo: %ld, ", SoloCount);
  290. X        fprintf(stderr, "Total: %ld\n", HashFill);
  291. X        fprintf(stderr, "Occurances: %.2f, ", aveOccur);
  292. X        fprintf(stderr, "Load: %.2f, ", loadFactor);
  293. X        fprintf(stderr, "Probes: %.2f\n", aveProbes);
  294. X    }
  295. X    exit(0);
  296. X}
  297. X
  298. Xvoid
  299. XextractId(getId, srcFILE, index)
  300. X    register char    *(*getId)();
  301. X    register FILE    *srcFILE;
  302. X    int        index;
  303. X{
  304. X    register struct idname    **slot;
  305. X    register char    *key;
  306. X    int        flags;
  307. X
  308. X    while ((key = (*getId)(srcFILE, &flags)) != NULL) {
  309. X        slot = (struct idname **)hashSearch(key, HashTable, HashSize, sizeof(struct idname *), h1str, h2str, idnHashCmp, &HashProbes);
  310. X        HashSearches++;
  311. X        if (*slot != NULL) {
  312. X            (*slot)->idn_flags |= flags;
  313. X            BITSET((*slot)->idn_bitv, index);
  314. X            continue;
  315. X        }
  316. X        *slot = newIdName(key);
  317. X        (*slot)->idn_flags = IDN_SOLO|flags;
  318. X        BITSET((*slot)->idn_bitv, index);
  319. X        if (HashFill++ >= HashMaxLoad)
  320. X            rehash();
  321. X    }
  322. X}
  323. X
  324. Xvoid
  325. XwriteID(idFile, idArgs)
  326. X    char        *idFile;
  327. X    struct idarg    *idArgs;
  328. X{
  329. X    register struct idname    **idnp;
  330. X    register struct idname    *idn;
  331. X    register int    i;
  332. X    char        *vecBuf;
  333. X    FILE        *idFILE;
  334. X    int        count;
  335. X    int        lasti;
  336. X    long        before, after;
  337. X    int        length, longest;
  338. X    struct idhead    idh;
  339. X
  340. X    if ((idFILE = fopen(idFile, "w+")) == NULL) {
  341. X        filerr("create", idFile);
  342. X        exit(1);
  343. X    }
  344. X    fseek(idFILE, (long)sizeof(struct idhead), 0);
  345. X
  346. X    /* write out the list of pathnames */
  347. X    idh.idh_argo = ftell(idFILE);
  348. X    for (i = lasti = 0; idArgs->ida_next; idArgs = idArgs->ida_next) {
  349. X        if (idArgs->ida_index > 0)
  350. X            while (++lasti < idArgs->ida_index)
  351. X                i++, putc('\0', idFILE);
  352. X        fputs(idArgs->ida_arg, idFILE);
  353. X        i++, putc('\0', idFILE);
  354. X    }
  355. X    idh.idh_argc = i;
  356. X    idh.idh_pthc = PathCount;
  357. X
  358. X    /* write out the list of identifiers */
  359. X    i = 1;
  360. X    if (idh.idh_pthc >= 0x000000ff)
  361. X        i++;
  362. X    if (idh.idh_pthc >= 0x0000ffff)
  363. X        i++;
  364. X    if (idh.idh_pthc >= 0x00ffffff)
  365. X        i++;
  366. X    idh.idh_vecc = i;
  367. X
  368. X    vecBuf = malloc((idh.idh_pthc + 1) * idh.idh_vecc);
  369. X
  370. X    putc('\377', idFILE);
  371. X    before = idh.idh_namo = ftell(idFILE);
  372. X    longest = 0;
  373. X    for (idnp = HashTable, i = 0; i < HashFill; i++, idnp++) {
  374. X        idn = *idnp;
  375. X        if (idn->idn_name[0] == '\0') {
  376. X            HashFill--; i--;
  377. X            continue;
  378. X        }
  379. X        if (idn->idn_flags & IDN_SOLO)
  380. X            SoloCount++;
  381. X        if (idn->idn_flags & IDN_NUMBER)
  382. X            NumberCount++;
  383. X        if (idn->idn_flags & IDN_NAME)
  384. X            NameCount++;
  385. X        if (idn->idn_flags & IDN_STRING)
  386. X            StringCount++;
  387. X
  388. X        putc((*idnp)->idn_flags, idFILE);
  389. X        fputs(idn->idn_name, idFILE);
  390. X        putc('\0', idFILE);
  391. X
  392. X        count = bitsToVec(vecBuf, (*idnp)->idn_bitv, idh.idh_pthc, idh.idh_vecc);
  393. X        fwrite(vecBuf, idh.idh_vecc, count, idFILE);
  394. X        putc('\377', idFILE);
  395. X        after = ftell(idFILE);
  396. X        
  397. X        if ((length = (after - before)) > longest)
  398. X            longest = length;
  399. X        before = after;
  400. X    }
  401. X    idh.idh_namc = i;
  402. X    putc('\377', idFILE);
  403. X    idh.idh_endo = ftell(idFILE);
  404. X    idh.idh_bsiz = longest;
  405. X
  406. X    /* write out the header */
  407. X    strncpy(idh.idh_magic, IDH_MAGIC, sizeof(idh.idh_magic));
  408. X    idh.idh_vers = IDH_VERS;
  409. X    fseek(idFILE, 0L, 0);
  410. X    fwrite(&idh, sizeof(struct idhead), 1, idFILE);
  411. X
  412. X    fclose(idFILE);
  413. X}
  414. X
  415. X/*
  416. X    Build an idarg vector from pathnames contained in an existing
  417. X    id file.  Only include pathnames for files whose modification
  418. X    time is later than that of the id file itself.
  419. X*/
  420. Xvoid
  421. XoldIdArgs(idFile, idArgsP)
  422. X    char        *idFile;
  423. X    struct idarg    **idArgsP;
  424. X{
  425. X    struct stat    statBuf;
  426. X    struct idhead    idh;
  427. X    FILE        *idFILE;
  428. X    register int    i;
  429. X    register char    *strings;
  430. X    time_t        idModTime;
  431. X
  432. X    if ((idFILE = fopen(idFile, "r")) == NULL) {
  433. X        filerr("open", idFile);
  434. X        usage();
  435. X    }
  436. X    /*
  437. X    *  Open the id file, get its mod-time, and read its header.
  438. X    */
  439. X    if (fstat(fileno(idFILE), &statBuf) < 0) {
  440. X        filerr("stat", idFile);
  441. X        usage();
  442. X    }
  443. X    idModTime = statBuf.st_mtime;
  444. X    fread(&idh, sizeof(struct idhead), 1, idFILE);
  445. X    if (!strnequ(idh.idh_magic, IDH_MAGIC, sizeof(idh.idh_magic))) {
  446. X        fprintf(stderr, "%s: Not an id file: `%s'\n", MyName, idFile);
  447. X        exit(1);
  448. X    }
  449. X    if (idh.idh_vers != IDH_VERS) {
  450. X        fprintf(stderr, "%s: ID version mismatch (%ld,%ld)\n", MyName, idh.idh_vers, IDH_VERS);
  451. X        exit(1);
  452. X    }
  453. X
  454. X    /*
  455. X    *  Read in the id pathnames, compare their mod-times with
  456. X    *  the id file, and incorporate the pathnames of recently modified 
  457. X    *  files in the idarg vector.  Also, construct a mask of
  458. X    *  bit array positions we want to turn off when we build the
  459. X    *  initial hash-table.
  460. X    */
  461. X    fseek(idFILE, idh.idh_argo, 0);
  462. X    strings = malloc(i = idh.idh_namo - idh.idh_argo);
  463. X    fread(strings, i, 1, idFILE);
  464. X    ScanCount = 0;
  465. X    for (i = 0; i < idh.idh_argc; i++) {
  466. X        (*idArgsP)->ida_arg = strings;
  467. X        if (*strings == '+' || *strings == '-') {
  468. X            (*idArgsP)->ida_flags = IDA_ARG;
  469. X            (*idArgsP)->ida_index = -1;
  470. X        } else {
  471. X            (*idArgsP)->ida_flags = IDA_PATH;
  472. X            (*idArgsP)->ida_index = postIncr(&PathCount);
  473. X            if (stat(strings, &statBuf) < 0) {
  474. X                filerr("stat", strings);
  475. X            } else if (statBuf.st_mtime >= idModTime) {
  476. X                (*idArgsP)->ida_flags |= IDA_SCAN;
  477. X                ScanCount++;
  478. X            }
  479. X        }
  480. X        (*idArgsP) = ((*idArgsP)->ida_next = NEW(struct idarg));
  481. X        while (*strings++)
  482. X            ;
  483. X    }
  484. X    if (ScanCount == 0) {
  485. X        fclose(idFILE);
  486. X        exit(0);
  487. X    }
  488. X    fclose(idFILE);
  489. X}
  490. X
  491. Xvoid
  492. XupdateID(idFile, idArgs)
  493. X    char        *idFile;
  494. X    struct idarg    *idArgs;
  495. X{
  496. X    struct idname    *idn;
  497. X    struct idhead    idh;
  498. X    register char    *bitArray;
  499. X    char        *entry;
  500. X    register int    i;
  501. X    FILE        *idFILE;
  502. X    int        cmp, count, size;
  503. X    char        *bitsOff;
  504. X    struct idname    **newTable, **mergeTable;
  505. X    struct idname    **t1, **t2, **tm;
  506. X
  507. X    if ((idFILE = fopen(idFile, "r")) == NULL)
  508. X        filerr("open", idFile);
  509. X    fread(&idh, sizeof(struct idhead), 1, idFILE);
  510. X
  511. X    entry = malloc(idh.idh_bsiz);
  512. X
  513. X    bitsOff = malloc(BitArraySize);
  514. X    bzero(bitsOff, BitArraySize);
  515. X    for (i = 0; idArgs->ida_next; idArgs = idArgs->ida_next)
  516. X        if (idArgs->ida_flags & IDA_SCAN)
  517. X            BITSET(bitsOff, idArgs->ida_index);
  518. X
  519. X    bitArray = malloc(BitArraySize);
  520. X    bzero(bitArray, BitArraySize);
  521. X    t2 = newTable = (struct idname **)malloc((idh.idh_namc + 1) * sizeof(struct idname *));
  522. X    fseek(idFILE, idh.idh_namo, 0);
  523. X    count = 0;
  524. X    for (i = 0; i < idh.idh_namc; i++) {
  525. X        size = 1 + fgets0(entry, idh.idh_bsiz, idFILE);
  526. X        getsFF(&entry[size], idFILE);
  527. X        vecToBits(bitArray, &entry[size], idh.idh_vecc);
  528. X        bitsclr(bitArray, bitsOff, BitArraySize);
  529. X        if (!bitsany(bitArray, BitArraySize))
  530. X            continue;
  531. X        *t2 = newIdName(ID_STRING(entry));
  532. X        bitsset((*t2)->idn_bitv, bitArray, BitArraySize);
  533. X        (*t2)->idn_flags = ID_FLAGS(entry);
  534. X        bzero(bitArray, BitArraySize);
  535. X        t2++; count++;
  536. X    }
  537. X    *t2 = NULL;
  538. X
  539. X    t1 = HashTable;
  540. X    t2 = newTable;
  541. X    tm = mergeTable = (struct idname **)calloc(HashFill + count + 1, sizeof(struct idname *));
  542. X    while (*t1 && *t2) {
  543. X        cmp = strcmp((*t1)->idn_name, (*t2)->idn_name);
  544. X        if (cmp < 0)
  545. X            *tm++ = *t1++;
  546. X        else if (cmp > 0)
  547. X            *tm++ = *t2++;
  548. X        else {
  549. X            (*t1)->idn_flags |= (*t2)->idn_flags;
  550. X            (*t1)->idn_flags &= ~IDN_SOLO;
  551. X            bitsset((*t1)->idn_bitv, (*t2)->idn_bitv, BitArraySize);
  552. X            *tm++ = *t1;
  553. X            t1++, t2++;
  554. X        }
  555. X    }
  556. X    while (*t1)
  557. X        *tm++ = *t1++;
  558. X    while (*t2)
  559. X        *tm++ = *t2++;
  560. X    *tm = NULL;
  561. X    HashTable = mergeTable;
  562. X    HashFill = tm - mergeTable;
  563. X}
  564. X
  565. X/*
  566. X    Cons up a list of idArgs as supplied in a file.
  567. X*/
  568. Xvoid
  569. XfileIdArgs(argFILE, idArgsP)
  570. X    FILE        *argFILE;
  571. X    struct idarg    **idArgsP;
  572. X{
  573. X    int        fileCount;
  574. X    char        buf[BUFSIZ];
  575. X    char        *arg;
  576. X
  577. X    fileCount = 0;
  578. X    while (fgets(buf, sizeof(buf), argFILE)) {
  579. X        (*idArgsP)->ida_arg = arg = strnsav(buf, strlen(buf)-1);
  580. X        if (*arg == '+' || *arg == '-') {
  581. X            (*idArgsP)->ida_flags = IDA_ARG;
  582. X            (*idArgsP)->ida_index = -1;
  583. X        } else {
  584. X            (*idArgsP)->ida_flags = IDA_SCAN|IDA_PATH;
  585. X            (*idArgsP)->ida_index = postIncr(&PathCount);
  586. X            ScanCount++;
  587. X        }
  588. X        (*idArgsP) = ((*idArgsP)->ida_next = NEW(struct idarg));
  589. X    }
  590. X}
  591. X
  592. Xvoid
  593. XinitHashTable(pathCount)
  594. X    int        pathCount;
  595. X{
  596. X    if ((HashSize = round2((pathCount << 6) + 511)) > 0x8000)
  597. X        HashSize = 0x8000;
  598. X    HashMaxLoad = HashSize - (HashSize >> 4);    /* about 94% */
  599. X    HashTable = (struct idname **)calloc(HashSize, sizeof(struct idname *));
  600. X}
  601. X
  602. X/*
  603. X    Double the size of the hash table in the
  604. X    event of overflow...
  605. X*/
  606. Xvoid
  607. Xrehash()
  608. X{
  609. X    long        oldHashSize = HashSize;
  610. X    struct idname    **oldHashTable = HashTable;
  611. X    register struct idname    **htp;
  612. X    register struct idname    **slot;
  613. X
  614. X    HashSize *= 2;
  615. X    if (Verbose)
  616. X        fprintf(stderr, "Rehashing... (doubling size to %ld)\n", HashSize);
  617. X    HashMaxLoad = HashSize - (HashSize >> 4);
  618. X    HashTable = (struct idname **)calloc(HashSize, sizeof(struct idname *));
  619. X
  620. X    HashFill = 0;
  621. X    for (htp = oldHashTable; htp < &oldHashTable[oldHashSize]; htp++) {
  622. X        if (*htp == NULL)
  623. X            continue;
  624. X        slot = (struct idname **)hashSearch((*htp)->idn_name, (char *)HashTable, HashSize, sizeof(struct idname *), h1str, h2str, idnHashCmp, &HashProbes);
  625. X        if (*slot) {
  626. X            fprintf(stderr, "%s: Duplicate hash entry!\n");
  627. X            exit(1);
  628. X        }
  629. X        *slot = *htp;
  630. X        HashSearches++;
  631. X        HashFill++;
  632. X    }
  633. X    free(oldHashTable);
  634. X}
  635. X
  636. X/*
  637. X    Round a given number up to the nearest power of 2.
  638. X*/
  639. Xint
  640. Xround2(rough)
  641. X    int        rough;
  642. X{
  643. X    int        round;
  644. X
  645. X    round = 1;
  646. X    while (rough) {
  647. X        round <<= 1;
  648. X        rough >>= 1;
  649. X    }
  650. X    return round;
  651. X}
  652. X
  653. X/*
  654. X    `compar' function for hashSearch()
  655. X*/
  656. Xint
  657. XidnHashCmp(key, idn)
  658. X    char        *key;
  659. X    struct idname    **idn;
  660. X{
  661. X    int        collate;
  662. X
  663. X    if (*idn == NULL)
  664. X        return 0;
  665. X    
  666. X    if ((collate = strcmp(key, (*idn)->idn_name)) == 0)
  667. X        (*idn)->idn_flags &= ~IDN_SOLO;    /* we found another occurance */
  668. X
  669. X    return collate;
  670. X}
  671. X
  672. X/*
  673. X    `compar' function for qsort().
  674. X*/
  675. Xint
  676. XidnQsortCmp(idn1, idn2)
  677. X    struct idname    **idn1;
  678. X    struct idname    **idn2;
  679. X{
  680. X    if (*idn1 == *idn2)
  681. X        return 0;
  682. X    if (*idn1 == NULL)
  683. X        return 1;
  684. X    if (*idn2 == NULL)
  685. X        return -1;
  686. X
  687. X    return strcmp((*idn1)->idn_name, (*idn2)->idn_name);
  688. X}
  689. X
  690. X/*
  691. X    Allocate a new idname struct and fill in the name field.
  692. X    We allocate memory in large chunks to avoid frequent
  693. X    calls to malloc() which is a major pig.
  694. X*/
  695. Xstruct idname *
  696. XnewIdName(name)
  697. X    char        *name;
  698. X{
  699. X    register struct idname    *idn;
  700. X    register char    *allocp;
  701. X    register int    allocsiz;
  702. X    static char    *allocBuf = NULL;
  703. X    static char    *allocEnd = NULL;
  704. X#define    ALLOCSIZ    (8*1024)
  705. X
  706. X    allocsiz = sizeof(struct idname) + strlen(name) + 1 + BitArraySize;
  707. X    allocsiz += (sizeof(long) - 1);
  708. X    allocsiz &= ~(sizeof(long) - 1);
  709. X
  710. X    allocp = allocBuf;
  711. X    allocBuf += allocsiz;
  712. X    if (allocBuf > allocEnd) {
  713. X        allocBuf = malloc(ALLOCSIZ);
  714. X        allocEnd = &allocBuf[ALLOCSIZ];
  715. X        allocp = allocBuf;
  716. X        allocBuf += allocsiz;
  717. X    }
  718. X
  719. X    idn = (struct idname *)allocp;
  720. X    allocp += sizeof(struct idname);
  721. X    idn->idn_bitv = allocp;
  722. X    for (allocsiz = BitArraySize; allocsiz--; allocp++)
  723. X        *allocp = '\0';
  724. X    idn->idn_name = strcpy(allocp, name);
  725. X
  726. X    return idn;
  727. X}
  728. X
  729. Xint
  730. XpostIncr(ip)
  731. X    int        *ip;
  732. X{
  733. X    register int    i;
  734. X    int        save;
  735. X
  736. X    save = *ip;
  737. X    i = save + 1;
  738. X    if ((i & 0x00ff) == 0x00ff)
  739. X        i++;
  740. X    if ((i & 0xff00) == 0xff00)    /* This isn't bloody likely */
  741. X        i += 0x100;
  742. X    *ip = i;
  743. X
  744. X    return save;
  745. X}
  746. X
  747. X/*
  748. X    Move all non-NULL table entries to the front of the table.
  749. X    return the number of non-NULL elements in the table.
  750. X*/
  751. Xint
  752. XhashCompress(table, size)
  753. X    char        **table;
  754. X    int        size;
  755. X{
  756. X    register char    **front;
  757. X    register char    **back;
  758. X
  759. X    front = &table[-1];
  760. X    back = &table[size];
  761. X
  762. X    for (;;) {
  763. X        while (*--back == NULL)
  764. X            ;
  765. X        if (back < front)
  766. X            break;
  767. X        while (*++front != NULL)
  768. X            ;
  769. X        if (back < front)
  770. X            break;
  771. X        *front = *back;
  772. X    }
  773. X
  774. X    return (back - table + 1);
  775. X}
  776. SHAR_EOF
  777. if test 17095 -ne "`wc -c < 'mkid.c'`"
  778. then
  779.     echo shar: error transmitting "'mkid.c'" '(should have been 17095 characters)'
  780. fi
  781. echo shar: extracting "'numtst.c'" '(60 characters)'
  782. sed 's/^X//' << \SHAR_EOF > 'numtst.c'
  783. X000004
  784. X00010
  785. X012
  786. X020
  787. X04
  788. X0x00004
  789. X0x00010
  790. X0x00a
  791. X0XA
  792. X10
  793. X16
  794. X4
  795. X8
  796. SHAR_EOF
  797. if test 60 -ne "`wc -c < 'numtst.c'`"
  798. then
  799.     echo shar: error transmitting "'numtst.c'" '(should have been 60 characters)'
  800. fi
  801. echo shar: extracting "'opensrc.c'" '(2172 characters)'
  802. sed 's/^X//' << \SHAR_EOF > 'opensrc.c'
  803. X/* Copyright (c) 1986, Greg McGary */
  804. Xstatic char sccsid[] = "@(#)opensrc.c    1.1 86/10/09";
  805. X
  806. X#include    <stdio.h>
  807. X#include    <string.h>
  808. X#include    <sys/types.h>
  809. X#include    <sys/stat.h>
  810. X
  811. XFILE *openSrcFILE();
  812. Xchar *getSCCS();
  813. Xchar *coRCS();
  814. X
  815. XFILE *
  816. XopenSrcFILE(path, sccsDir, rcsDir)
  817. X    char        *path;
  818. X    char        *sccsDir;
  819. X    char        *rcsDir;
  820. X{
  821. X    char        *command = NULL;
  822. X    char        *what = NULL;
  823. X    char        *get = "get SCCS file";
  824. X    char        *checkout = "checkout RCS file";
  825. X    char        *dirName;
  826. X    char        *baseName;
  827. X    FILE        *srcFILE;
  828. X
  829. X    if ((srcFILE = fopen(path, "r")) != NULL)
  830. X        return srcFILE;
  831. X
  832. X    if ((baseName = strrchr(path, '/')) == NULL) {
  833. X        dirName = ".";
  834. X        baseName = path;
  835. X    } else {
  836. X        dirName = path;
  837. X        *baseName++ = '\0';
  838. X    }
  839. X
  840. X    if (rcsDir && (command = coRCS(dirName, baseName, rcsDir)))
  841. X        what = checkout;
  842. X    else if (sccsDir && (command = getSCCS(dirName, baseName, sccsDir)))
  843. X        what = get;
  844. X    else if ((command = coRCS(dirName, baseName, "RCS"))
  845. X         ||  (command = coRCS(dirName, baseName, ".")))
  846. X        what = checkout;
  847. X    else if ((command = getSCCS(dirName, baseName, "SCCS"))
  848. X         ||  (command = getSCCS(dirName, baseName, "sccs"))
  849. X         ||  (command = getSCCS(dirName, baseName, ".")))
  850. X        what = get;
  851. X
  852. X    if (dirName == path)
  853. X        *--baseName = '/';
  854. X
  855. X    if (!command) {
  856. X        filerr("open", path);
  857. X        return NULL;
  858. X    }
  859. X
  860. X    system(command);
  861. X    if ((srcFILE = fopen(path, "r")) == NULL) {
  862. X        filerr("open", path);
  863. X        return NULL;
  864. X    }
  865. X
  866. X    fprintf(stderr, "%s\n", command);
  867. X    return srcFILE;
  868. X}
  869. X
  870. Xchar *
  871. XgetSCCS(dir, base, sccsDir)
  872. X    char        *dir;
  873. X    char        *base;
  874. X    char        *sccsDir;
  875. X{
  876. X    static char    cmdBuf[BUFSIZ];
  877. X    char        fileBuf[BUFSIZ];
  878. X    struct stat    statBuf;
  879. X
  880. X    if (!*sccsDir)
  881. X        sccsDir = ".";
  882. X
  883. X    sprintf(fileBuf, "%s/%s/s.%s", dir, sccsDir, base);
  884. X    if (stat(fileBuf, &statBuf) < 0)
  885. X        return NULL;
  886. X    sprintf(cmdBuf, "cd %s; get -s %s/s.%s", dir, sccsDir, base);
  887. X
  888. X    return cmdBuf;
  889. X}
  890. X
  891. Xchar *
  892. XcoRCS(dir, base, rcsDir)
  893. X    char        *dir;
  894. X    char        *base;
  895. X    char        *rcsDir;
  896. X{
  897. X    static char    cmdBuf[BUFSIZ];
  898. X    char        fileBuf[BUFSIZ];
  899. X    struct stat    statBuf;
  900. X
  901. X    if (!*rcsDir)
  902. X        rcsDir = ".";
  903. X
  904. X    sprintf(fileBuf, "%s/%s/%s,v", dir, rcsDir, base);
  905. X    if (stat(fileBuf, &statBuf) < 0)
  906. X        return NULL;
  907. X    sprintf(cmdBuf, "cd %s; co -q %s/%s,v", dir, rcsDir, base);
  908. X
  909. X    return cmdBuf;
  910. X}
  911. SHAR_EOF
  912. if test 2172 -ne "`wc -c < 'opensrc.c'`"
  913. then
  914.     echo shar: error transmitting "'opensrc.c'" '(should have been 2172 characters)'
  915. fi
  916. echo shar: extracting "'paths.c'" '(3629 characters)'
  917. sed 's/^X//' << \SHAR_EOF > 'paths.c'
  918. X/* Copyright (c) 1986, Greg McGary */
  919. Xstatic char sccsid[] = "@(#)paths.c    1.1 86/10/09";
  920. X
  921. X#include    <bool.h>
  922. X#include    <stdio.h>
  923. X#include    <string.h>
  924. X
  925. Xbool canCrunch();
  926. Xchar *getDirToName();
  927. Xchar *rootName();
  928. Xchar *skipJunk();
  929. Xchar *spanPath();
  930. Xchar *suffName();
  931. X
  932. Xchar *
  933. XspanPath(dir, arg)
  934. X    char        *dir;
  935. X    char        *arg;
  936. X{
  937. X    static char    pathBuf[BUFSIZ];
  938. X    char        *path;
  939. X    char        *argTail;
  940. X    char        *dirTail;
  941. X    int        argLength;
  942. X    int        dirLength;
  943. X
  944. X    for (dirTail = &dir[strlen(dir)-1]; *dirTail == '/'; dirTail--)
  945. X        *dirTail = '\0';
  946. X    for (;;) {
  947. X        dir = skipJunk(dir);
  948. X        if ((dirTail = strchr(dir, '/')) == NULL)
  949. X            dirTail = &dir[strlen(dir)];
  950. X        dirLength = dirTail - dir;
  951. X
  952. X        arg = skipJunk(arg);
  953. X        if ((argTail = strchr(arg, '/')) == NULL)
  954. X            break;
  955. X        argLength = argTail - arg;
  956. X
  957. X        if (argLength != dirLength)
  958. X            break;
  959. X        if (!strnequ(arg, dir, argLength))
  960. X            break;
  961. X        arg = argTail;
  962. X        dir = dirTail;
  963. X    }
  964. X
  965. X    (path = pathBuf)[0] = '\0';
  966. X    for (; dir && *dir; dir = skipJunk(strchr(dir, '/'))) {
  967. X        strcpy(path, "../");
  968. X        path += 3;
  969. X    }
  970. X    strcat(path, arg);
  971. X    return pathBuf;
  972. X}
  973. X
  974. Xchar *
  975. XskipJunk(path)
  976. X    char        *path;
  977. X{
  978. X    if (path == NULL)
  979. X        return NULL;
  980. X    while (*path == '/')
  981. X        path++;
  982. X    while (path[0] == '.' && path[1] == '/') {
  983. X        path += 2;
  984. X        while (*path == '/')
  985. X            path++;
  986. X    }
  987. X    if (strequ(path, "."))
  988. X        path++;
  989. X    
  990. X    return path;
  991. X}
  992. X
  993. Xchar *
  994. XrootName(path)
  995. X    char        *path;
  996. X{
  997. X    static char    pathBuf[BUFSIZ];
  998. X    char        *root;
  999. X    char        *dot;
  1000. X
  1001. X    if ((root = strrchr(path, '/')) == NULL)
  1002. X        root = path;
  1003. X    else
  1004. X        root++;
  1005. X    
  1006. X    if ((dot = strrchr(root, '.')) == NULL)
  1007. X        strcpy(pathBuf, root);
  1008. X    else {
  1009. X        strncpy(pathBuf, root, dot - root);
  1010. X        pathBuf[dot - root] = '\0';
  1011. X    }
  1012. X    return pathBuf;
  1013. X}
  1014. X
  1015. Xchar *
  1016. XsuffName(path)
  1017. X    char        *path;
  1018. X{
  1019. X    char        *dot;
  1020. X
  1021. X    if ((dot = strrchr(path, '.')) == NULL)
  1022. X        return "";
  1023. X    return dot;
  1024. X}
  1025. X
  1026. Xbool
  1027. XcanCrunch(path1, path2)
  1028. X    char        *path1;
  1029. X    char        *path2;
  1030. X{
  1031. X    char        *slash1;
  1032. X    char        *slash2;
  1033. X
  1034. X    slash1 = strrchr(path1, '/');
  1035. X    slash2 = strrchr(path2, '/');
  1036. X
  1037. X    if (slash1 == NULL && slash2 == NULL)
  1038. X        return strequ(suffName(path1), suffName(path2));
  1039. X    if ((slash1 - path1) != (slash2 - path2))
  1040. X        return FALSE;
  1041. X    if (!strnequ(path1, path2, slash1 - path1))
  1042. X        return FALSE;
  1043. X    return strequ(suffName(slash1), suffName(slash2));
  1044. X}
  1045. X#include    <sys/types.h>
  1046. X#include    <sys/stat.h>
  1047. X#ifdef NDIR
  1048. X#include    <ndir.h>
  1049. X#else
  1050. X#include    <sys/dir.h>
  1051. X#endif
  1052. X
  1053. Xstatic char    dot[]     = ".";
  1054. Xstatic char    dotdot[] = "..";
  1055. X
  1056. X/*
  1057. X    Return our directory name relative to the first parent dir
  1058. X    that contains a file with a name that matches `topName'.
  1059. X    Fail if we hit the root, or if any dir in our way is unreadable.
  1060. X*/
  1061. Xchar *
  1062. XgetDirToName(topName)
  1063. X    char        *topName;
  1064. X{
  1065. X    register struct direct    *dirp;
  1066. X    register DIR    *dirdp;
  1067. X    static char    nameBuf[BUFSIZ];
  1068. X    char        *name;
  1069. X    struct    stat    dStat;
  1070. X    struct    stat    ddStat;
  1071. X
  1072. X    name = &nameBuf[sizeof(nameBuf)-1];
  1073. X    *name = '\0';
  1074. X    for (;;) {
  1075. X        if (stat(topName, &dStat) == 0) {
  1076. X            if (!*name)
  1077. X                name = dot;
  1078. X            else
  1079. X                chdir(name);
  1080. X            return name;
  1081. X        } if (stat(dot, &dStat) < 0)
  1082. X            return NULL;
  1083. X        if ((dirdp = opendir(dotdot)) == NULL)
  1084. X            return NULL;
  1085. X        if (fstat(dirdp->dd_fd, &ddStat) < 0)
  1086. X            return NULL;
  1087. X        if (chdir(dotdot) < 0)
  1088. X            return NULL;
  1089. X        if (dStat.st_dev == ddStat.st_dev) {
  1090. X            if (dStat.st_ino == ddStat.st_ino)
  1091. X                return NULL;
  1092. X            do {
  1093. X                if ((dirp = readdir(dirdp)) == NULL)
  1094. X                    return NULL;
  1095. X            } while (dirp->d_ino != dStat.st_ino);
  1096. X        } else {
  1097. X            do {
  1098. X                if ((dirp = readdir(dirdp)) == NULL)
  1099. X                    return NULL;
  1100. X                stat(dirp->d_name, &ddStat);
  1101. X            } while (ddStat.st_ino != dStat.st_ino || ddStat.st_dev != dStat.st_dev);
  1102. X        }
  1103. X        closedir(dirdp);
  1104. X    
  1105. X        if (*name != '\0')
  1106. X            *--name = '/';
  1107. X        name -= dirp->d_namlen;
  1108. X        strncpy(name, dirp->d_name, dirp->d_namlen);
  1109. X    }
  1110. X}
  1111. SHAR_EOF
  1112. if test 3629 -ne "`wc -c < 'paths.c'`"
  1113. then
  1114.     echo shar: error transmitting "'paths.c'" '(should have been 3629 characters)'
  1115. fi
  1116. echo shar: extracting "'scan-asm.c'" '(6157 characters)'
  1117. sed 's/^X//' << \SHAR_EOF > 'scan-asm.c'
  1118. X/* Copyright (c) 1986, Greg McGary */
  1119. Xstatic char sccsid[] = "@(#)scan-asm.c    1.2 86/11/06";
  1120. X
  1121. X#include    <bool.h>
  1122. X#include    <stdio.h>
  1123. X#include    <string.h>
  1124. X#include    <ctype.h>
  1125. X#include    <id.h>
  1126. X
  1127. Xchar *getAsmId();
  1128. Xvoid setAsmArgs();
  1129. X
  1130. Xstatic void clrCtype();
  1131. Xstatic void setCtype();
  1132. X
  1133. X#define    I1    0x01    /* 1st char of an identifier [a-zA-Z_] */
  1134. X#define    NM    0x02    /* digit [0-9a-fA-FxX] */
  1135. X#define    NL    0x04    /* newline: \n */
  1136. X#define    CM    0x08    /* assembler comment char: usually # or | */
  1137. X#define    IG    0x10    /* ignore `identifiers' with these chars in them */
  1138. X#define    C1    0x20    /* C comment introduction char: / */
  1139. X#define    C2    0x40    /* C comment termination  char: * */
  1140. X#define    EF    0x80    /* EOF */
  1141. X
  1142. X/* Assembly Language character classes */
  1143. X#define    ISID1ST(c)    ((rct)[c]&(I1))
  1144. X#define    ISIDREST(c)    ((rct)[c]&(I1|NM))
  1145. X#define    ISNUMBER(c)    ((rct)[c]&(NM))
  1146. X#define    ISEOF(c)    ((rct)[c]&(EF))
  1147. X#define    ISCOMMENT(c)    ((rct)[c]&(CM))
  1148. X#define    ISBORING(c)    (!((rct)[c]&(EF|NL|I1|NM|CM|C1)))
  1149. X#define    ISCBORING(c)    (!((rct)[c]&(EF|NL)))
  1150. X#define    ISCCBORING(c)    (!((rct)[c]&(EF|C2)))
  1151. X#define    ISIGNORE(c)    ((rct)[c]&(IG))
  1152. X
  1153. Xstatic char idctype[] = {
  1154. X
  1155. X    EF,
  1156. X
  1157. X    /*      0       1       2       3       4       5       6       7   */
  1158. X    /*    -----   -----   -----   -----   -----   -----   -----   ----- */
  1159. X
  1160. X    /*000*/    0,    0,    0,    0,    0,    0,    0,    0,
  1161. X    /*010*/    0,    0,    NL,    0,    0,    0,    0,    0,
  1162. X    /*020*/    0,    0,    0,    0,    0,    0,    0,    0,
  1163. X    /*030*/    0,    0,    0,    0,    0,    0,    0,    0,
  1164. X    /*040*/    0,    0,    0,    0,    0,    0,    0,    0,
  1165. X    /*050*/    0,    0,    C2,    0,    0,    0,    0,    C1,
  1166. X    /*060*/    NM,    NM,    NM,    NM,    NM,    NM,    NM,    NM,    
  1167. X    /*070*/    NM,    NM,    0,    0,    0,    0,    0,    0,
  1168. X    /*100*/    0,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1,
  1169. X    /*110*/    I1,    I1,    I1,    I1,    I1|NM,    I1,    I1,    I1,
  1170. X    /*120*/    I1,    I1,    I1,    I1,    I1,    I1,    I1,    I1,
  1171. X    /*130*/    I1|NM,    I1,    I1,    0,    0,    0,    0,    I1,
  1172. X    /*140*/    0,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1,
  1173. X    /*150*/    I1,    I1,    I1,    I1,    I1|NM,    I1,    I1,    I1,
  1174. X    /*160*/    I1,    I1,    I1,    I1,    I1,    I1,    I1,    I1,
  1175. X    /*170*/    I1|NM,    I1,    I1,    0,    0,    0,    0,    0,
  1176. X
  1177. X    /*200*/    0,    0,    0,    0,    0,    0,    0,    0,
  1178. X    /*210*/    0,    0,    0,    0,    0,    0,    0,    0,
  1179. X    /*220*/    0,    0,    0,    0,    0,    0,    0,    0,
  1180. X    /*230*/    0,    0,    0,    0,    0,    0,    0,    0,
  1181. X    /*240*/    0,    0,    0,    0,    0,    0,    0,    0,
  1182. X    /*250*/    0,    0,    0,    0,    0,    0,    0,    0,
  1183. X    /*260*/    0,    0,    0,    0,    0,    0,    0,    0,
  1184. X    /*270*/    0,    0,    0,    0,    0,    0,    0,    0,
  1185. X    /*300*/    0,    0,    0,    0,    0,    0,    0,    0,
  1186. X    /*310*/    0,    0,    0,    0,    0,    0,    0,    0,
  1187. X    /*320*/    0,    0,    0,    0,    0,    0,    0,    0,
  1188. X    /*330*/    0,    0,    0,    0,    0,    0,    0,    0,
  1189. X    /*340*/    0,    0,    0,    0,    0,    0,    0,    0,
  1190. X    /*350*/    0,    0,    0,    0,    0,    0,    0,    0,
  1191. X    /*360*/    0,    0,    0,    0,    0,    0,    0,    0,
  1192. X    /*370*/    0,    0,    0,    0,    0,    0,    0,    0,
  1193. X
  1194. X};
  1195. X
  1196. Xstatic bool eatUnder = TRUE;
  1197. Xstatic bool preProcess = TRUE;
  1198. X
  1199. X/*
  1200. X    Grab the next identifier the assembly language
  1201. X    source file opened with the handle `inFILE'.
  1202. X    This state machine is built for speed, not elegance.
  1203. X*/
  1204. Xchar *
  1205. XgetAsmId(inFILE, flagP)
  1206. X    FILE        *inFILE;
  1207. X    int        *flagP;
  1208. X{
  1209. X    static char    idBuf[BUFSIZ];
  1210. X    register char    *rct = &idctype[1];
  1211. X    register int    c;
  1212. X    register char    *id = idBuf;
  1213. X    static bool    newLine = TRUE;
  1214. X
  1215. Xtop:
  1216. X    c = getc(inFILE);
  1217. X    if (preProcess > 0 && newLine) {
  1218. X        newLine = FALSE;
  1219. X        if (c != '#')
  1220. X            goto next;
  1221. X        while (ISBORING(c))
  1222. X            c = getc(inFILE);
  1223. X        if (!ISID1ST(c))
  1224. X            goto next;
  1225. X        id = idBuf;
  1226. X        *id++ = c;
  1227. X        while (ISIDREST(c = getc(inFILE)))
  1228. X            *id++ = c;
  1229. X        *id = '\0';
  1230. X        if (strequ(idBuf, "include")) {
  1231. X            while (c != '"' && c != '<')
  1232. X                c = getc(inFILE);
  1233. X            id = idBuf;
  1234. X            *id++ = c = getc(inFILE);
  1235. X            while ((c = getc(inFILE)) != '"' && c != '>')
  1236. X                *id++ = c;
  1237. X            *id = '\0';
  1238. X            *flagP = IDN_STRING;
  1239. X            return idBuf;
  1240. X        }
  1241. X        if (strnequ(idBuf, "if", 2)
  1242. X        || strequ(idBuf, "define")
  1243. X        || strequ(idBuf, "undef"))
  1244. X            goto next;
  1245. X        while (c != '\n')
  1246. X            c = getc(inFILE);
  1247. X        newLine = TRUE;
  1248. X        goto top;
  1249. X    }
  1250. X
  1251. Xnext:
  1252. X    while (ISBORING(c))
  1253. X        c = getc(inFILE);
  1254. X
  1255. X    if (ISCOMMENT(c)) {
  1256. X        while (ISCBORING(c))
  1257. X            c = getc(inFILE);
  1258. X        newLine = TRUE;
  1259. X    }
  1260. X
  1261. X    if (ISEOF(c)) {
  1262. X        newLine = TRUE;
  1263. X        return NULL;
  1264. X    }
  1265. X
  1266. X    if (c == '\n') {
  1267. X        newLine = TRUE;
  1268. X        goto top;
  1269. X    }
  1270. X
  1271. X    if (c == '/') {
  1272. X        if ((c = getc(inFILE)) != '*')
  1273. X            goto next;
  1274. X        c = getc(inFILE);
  1275. X        for (;;) {
  1276. X            while (ISCCBORING(c))
  1277. X                c = getc(inFILE);
  1278. X            if ((c = getc(inFILE)) == '/') {
  1279. X                c = getc(inFILE);
  1280. X                break;
  1281. X            } else if (ISEOF(c)) {
  1282. X                newLine = TRUE;
  1283. X                return NULL;
  1284. X            }
  1285. X        }
  1286. X        goto next;
  1287. X    }
  1288. X
  1289. X    id = idBuf;
  1290. X    if (eatUnder && c == '_' && !ISID1ST(c = getc(inFILE))) {
  1291. X        ungetc(c, inFILE);
  1292. X        return "_";
  1293. X    }
  1294. X    *id++ = c;
  1295. X    if (ISID1ST(c)) {
  1296. X        *flagP = IDN_NAME;
  1297. X        while (ISIDREST(c = getc(inFILE)))
  1298. X            *id++ = c;
  1299. X    } else if (ISNUMBER(c)) {
  1300. X        *flagP = IDN_NUMBER;
  1301. X        while (ISNUMBER(c = getc(inFILE)))
  1302. X            *id++ = c;
  1303. X    } else {
  1304. X        if (isprint(c))
  1305. X            fprintf(stderr, "junk: `%c'", c);
  1306. X        else
  1307. X            fprintf(stderr, "junk: `\\%03o'", c);
  1308. X        goto next;
  1309. X    }
  1310. X
  1311. X    *id = '\0';
  1312. X    for (id = idBuf; *id; id++)
  1313. X        if (ISIGNORE(*id))
  1314. X            goto next;
  1315. X    ungetc(c, inFILE);
  1316. X    *flagP |= IDN_LITERAL;
  1317. X    return idBuf;
  1318. X}
  1319. X
  1320. Xstatic void
  1321. XsetCtype(chars, type)
  1322. X    char        *chars;
  1323. X    int        type;
  1324. X{
  1325. X    char        *rct = &idctype[1];
  1326. X
  1327. X    while (*chars)
  1328. X        rct[*chars++] |= type;
  1329. X}
  1330. Xstatic void
  1331. XclrCtype(chars, type)
  1332. X    char        *chars;
  1333. X    int        type;
  1334. X{
  1335. X    char        *rct = &idctype[1];
  1336. X
  1337. X    while (*chars)
  1338. X        rct[*chars++] &= ~type;
  1339. X}
  1340. X
  1341. Xextern char    *MyName;
  1342. Xstatic void
  1343. Xusage(lang)
  1344. X    char        *lang;
  1345. X{
  1346. X    fprintf(stderr, "Usage: %s -S%s([-c<cc>] [-u] [(+|-)a<cc>] [(+|-)p] [(+|-)C])\n", MyName, lang);
  1347. X    exit(1);
  1348. X}
  1349. Xstatic char *asmDocument[] =
  1350. X{
  1351. X"The Assembler scanner arguments take the form -Sasm<arg>, where",
  1352. X"<arg> is one of the following: (<cc> denotes one or more characters)",
  1353. X"  -c<cc> . . . . <cc> introduce(s) a comment until end-of-line.",
  1354. X"  (+|-)u . . . . (Do|Don't) strip a leading `_' from ids.",
  1355. X"  (+|-)a<cc> . . Allow <cc> in ids, and (keep|ignore) those ids.",
  1356. X"  (+|-)p . . . . (Do|Don't) handle C-preprocessor directives.",
  1357. X"  (+|-)C . . . . (Do|Don't) handle C-style comments. (/* */)",
  1358. XNULL
  1359. X};
  1360. Xvoid
  1361. XsetAsmArgs(lang, op, arg)
  1362. X    char        *lang;
  1363. X    int        op;
  1364. X    char        *arg;
  1365. X{
  1366. X    if (op == '?') {
  1367. X        document(asmDocument);
  1368. X        return;
  1369. X    }
  1370. X    switch (*arg++)
  1371. X    {
  1372. X    case 'a':
  1373. X        setCtype(arg, I1|((op == '-') ? IG : 0));
  1374. X        break;
  1375. X    case 'c':
  1376. X        setCtype(arg, CM);
  1377. X        break;
  1378. X    case 'u':
  1379. X        eatUnder = (op == '+');
  1380. X        break;
  1381. X    case 'p':
  1382. X        preProcess = (op == '+');
  1383. X        break;
  1384. X    case 'C':
  1385. X        if (op == '+') {
  1386. X            setCtype("/", C1);
  1387. X            setCtype("*", C2);
  1388. X        } else {
  1389. X            clrCtype("/", C1);
  1390. X            clrCtype("*", C2);
  1391. X        }
  1392. X        break;
  1393. X    default:
  1394. X        if (lang)
  1395. X            usage(lang);
  1396. X        break;
  1397. X    }
  1398. X}
  1399. SHAR_EOF
  1400. if test 6157 -ne "`wc -c < 'scan-asm.c'`"
  1401. then
  1402.     echo shar: error transmitting "'scan-asm.c'" '(should have been 6157 characters)'
  1403. fi
  1404. echo shar: extracting "'scan-c.c'" '(6502 characters)'
  1405. sed 's/^X//' << \SHAR_EOF > 'scan-c.c'
  1406. X/* Copyright (c) 1986, Greg McGary */
  1407. Xstatic char sccsid[] = "@(#)scan-c.c    1.1 86/10/09";
  1408. X
  1409. X#include    <bool.h>
  1410. X#include    <stdio.h>
  1411. X#include    <string.h>
  1412. X#include    <id.h>
  1413. X
  1414. Xchar *getCId();
  1415. Xvoid setCArgs();
  1416. X
  1417. Xstatic void clrCtype();
  1418. Xstatic void setCtype();
  1419. X
  1420. X#define    I1    0x0001    /* 1st char of an identifier [a-zA-Z_] */
  1421. X#define    DG    0x0002    /* decimal digit [0-9] */
  1422. X#define    NM    0x0004    /* extra chars in a hex or long number [a-fA-FxXlL] */
  1423. X#define    C1    0x0008    /* C comment introduction char: / */
  1424. X#define    C2    0x0010    /* C comment termination  char: * */
  1425. X#define    Q1    0x0020    /* single quote: ' */
  1426. X#define    Q2    0x0040    /* double quote: " */
  1427. X#define    ES    0x0080    /* escape char: \ */
  1428. X#define    NL    0x0100    /* newline: \n */
  1429. X#define    EF    0x0200    /* EOF */
  1430. X#define    SK    0x0400    /* Make these chars valid for names within strings */
  1431. X
  1432. X/*
  1433. X    character class membership macros:
  1434. X*/
  1435. X#define    ISDIGIT(c)    ((rct)[c]&(DG))        /* digit */
  1436. X#define    ISNUMBER(c)    ((rct)[c]&(DG|NM))    /* legal in a number */
  1437. X#define    ISEOF(c)    ((rct)[c]&(EF))        /* EOF */
  1438. X#define    ISID1ST(c)    ((rct)[c]&(I1))        /* 1st char of an identifier */
  1439. X#define    ISIDREST(c)    ((rct)[c]&(I1|DG))    /* rest of an identifier */
  1440. X#define    ISSTRKEEP(c)    ((rct)[c]&(I1|DG|SK))    /* keep contents of string */
  1441. X/*
  1442. X    The `BORING' classes should be skipped over
  1443. X    until something interesting comes along...
  1444. X*/
  1445. X#define    ISBORING(c)    (!((rct)[c]&(EF|NL|I1|DG|Q1|Q2|C1)))    /* fluff */
  1446. X#define    ISCBORING(c)    (!((rct)[c]&(EF|C2)))    /* comment fluff */
  1447. X#define    ISQ1BORING(c)    (!((rct)[c]&(EF|NL|Q1|ES)))    /* char const fluff */
  1448. X#define    ISQ2BORING(c)    (!((rct)[c]&(EF|NL|Q2|ES)))    /* quoted str fluff */
  1449. X
  1450. Xstatic short idctype[] = {
  1451. X
  1452. X    EF,
  1453. X
  1454. X    /*      0       1       2       3       4       5       6       7   */
  1455. X    /*    -----   -----   -----   -----   -----   -----   -----   ----- */
  1456. X
  1457. X    /*000*/    0,    0,    0,    0,    0,    0,    0,    0,
  1458. X    /*010*/    0,    0,    NL,    0,    0,    0,    0,    0,
  1459. X    /*020*/    0,    0,    0,    0,    0,    0,    0,    0,
  1460. X    /*030*/    0,    0,    0,    0,    0,    0,    0,    0,
  1461. X    /*040*/    0,    0,    Q2,    0,    0,    0,    0,    Q1,
  1462. X    /*050*/    0,    0,    C2,    0,    0,    0,    0,    C1,
  1463. X    /*060*/    DG,    DG,    DG,    DG,    DG,    DG,    DG,    DG,    
  1464. X    /*070*/    DG,    DG,    0,    0,    0,    0,    0,    0,
  1465. X    /*100*/    0,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1,
  1466. X    /*110*/    I1,    I1,    I1,    I1,    I1|NM,    I1,    I1,    I1,
  1467. X    /*120*/    I1,    I1,    I1,    I1,    I1,    I1,    I1,    I1,
  1468. X    /*130*/    I1|NM,    I1,    I1,    0,    ES,    0,    0,    I1,
  1469. X    /*140*/    0,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1|NM,    I1,
  1470. X    /*150*/    I1,    I1,    I1,    I1,    I1|NM,    I1,    I1,    I1,
  1471. X    /*160*/    I1,    I1,    I1,    I1,    I1,    I1,    I1,    I1,
  1472. X    /*170*/    I1|NM,    I1,    I1,    0,    0,    0,    0,    0,
  1473. X
  1474. X    /*200*/    0,    0,    0,    0,    0,    0,    0,    0,
  1475. X    /*210*/    0,    0,    0,    0,    0,    0,    0,    0,
  1476. X    /*220*/    0,    0,    0,    0,    0,    0,    0,    0,
  1477. X    /*230*/    0,    0,    0,    0,    0,    0,    0,    0,
  1478. X    /*240*/    0,    0,    0,    0,    0,    0,    0,    0,
  1479. X    /*250*/    0,    0,    0,    0,    0,    0,    0,    0,
  1480. X    /*260*/    0,    0,    0,    0,    0,    0,    0,    0,
  1481. X    /*270*/    0,    0,    0,    0,    0,    0,    0,    0,
  1482. X    /*300*/    0,    0,    0,    0,    0,    0,    0,    0,
  1483. X    /*310*/    0,    0,    0,    0,    0,    0,    0,    0,
  1484. X    /*320*/    0,    0,    0,    0,    0,    0,    0,    0,
  1485. X    /*330*/    0,    0,    0,    0,    0,    0,    0,    0,
  1486. X    /*340*/    0,    0,    0,    0,    0,    0,    0,    0,
  1487. X    /*350*/    0,    0,    0,    0,    0,    0,    0,    0,
  1488. X    /*360*/    0,    0,    0,    0,    0,    0,    0,    0,
  1489. X    /*370*/    0,    0,    0,    0,    0,    0,    0,    0,
  1490. X
  1491. X};
  1492. X
  1493. Xstatic bool eatUnder = TRUE;
  1494. X
  1495. X/*
  1496. X    Grab the next identifier the C source
  1497. X    file opened with the handle `inFILE'.
  1498. X    This state machine is built for speed, not elegance.
  1499. X*/
  1500. Xchar *
  1501. XgetCId(inFILE, flagP)
  1502. X    FILE        *inFILE;
  1503. X    int        *flagP;
  1504. X{
  1505. X    static char    idBuf[BUFSIZ];
  1506. X    static bool    newLine = TRUE;
  1507. X    register short    *rct = &idctype[1];
  1508. X    register int    c;
  1509. X    register char    *id = idBuf;
  1510. X
  1511. Xtop:
  1512. X    c = getc(inFILE);
  1513. X    if (newLine) {
  1514. X        newLine = FALSE;
  1515. X        if (c != '#')
  1516. X            goto next;
  1517. X        while (ISBORING(c))
  1518. X            c = getc(inFILE);
  1519. X        if (!ISID1ST(c))
  1520. X            goto next;
  1521. X        id = idBuf;
  1522. X        *id++ = c;
  1523. X        while (ISIDREST(c = getc(inFILE)))
  1524. X            *id++ = c;
  1525. X        *id = '\0';
  1526. X        if (strequ(idBuf, "include")) {
  1527. X            while (c != '"' && c != '<')
  1528. X                c = getc(inFILE);
  1529. X            id = idBuf;
  1530. X            *id++ = c = getc(inFILE);
  1531. X            while ((c = getc(inFILE)) != '"' && c != '>')
  1532. X                *id++ = c;
  1533. X            *id = '\0';
  1534. X            *flagP = IDN_STRING;
  1535. X            return idBuf;
  1536. X        }
  1537. X        if (strnequ(idBuf, "if", 2)
  1538. X        || strequ(idBuf, "define")
  1539. X        || strequ(idBuf, "undef"))
  1540. X            goto next;
  1541. X        while (c != '\n')
  1542. X            c = getc(inFILE);
  1543. X        newLine = TRUE;
  1544. X        goto top;
  1545. X    }
  1546. X
  1547. Xnext:
  1548. X    while (ISBORING(c))
  1549. X        c = getc(inFILE);
  1550. X
  1551. X    switch (c)
  1552. X    {
  1553. X    case '"':
  1554. X        id = idBuf;
  1555. X        *id++ = c = getc(inFILE);
  1556. X        for (;;) {
  1557. X            while (ISQ2BORING(c))
  1558. X                *id++ = c = getc(inFILE);
  1559. X            if (c == '\\') {
  1560. X                *id++ = c = getc(inFILE);
  1561. X                continue;
  1562. X            } else if (c != '"')
  1563. X                goto next;
  1564. X            break;
  1565. X        }
  1566. X        *--id = '\0';
  1567. X        id = idBuf;
  1568. X        while (ISSTRKEEP(*id))
  1569. X            id++;
  1570. X        if (*id || id == idBuf) {
  1571. X            c = getc(inFILE);
  1572. X            goto next;
  1573. X        }
  1574. X        *flagP = IDN_STRING;
  1575. X        if (eatUnder && idBuf[0] == '_' && idBuf[1])
  1576. X            return &idBuf[1];
  1577. X        else
  1578. X            return idBuf;
  1579. X        
  1580. X    case '\'':
  1581. X        c = getc(inFILE);
  1582. X        for (;;) {
  1583. X            while (ISQ1BORING(c))
  1584. X                c = getc(inFILE);
  1585. X            if (c == '\\') {
  1586. X                c = getc(inFILE);
  1587. X                continue;
  1588. X            } else if (c == '\'')
  1589. X                c = getc(inFILE);
  1590. X            goto next;
  1591. X        }
  1592. X
  1593. X    case '/':
  1594. X        if ((c = getc(inFILE)) != '*')
  1595. X            goto next;
  1596. X        c = getc(inFILE);
  1597. X        for (;;) {
  1598. X            while (ISCBORING(c))
  1599. X                c = getc(inFILE);
  1600. X            if ((c = getc(inFILE)) == '/') {
  1601. X                c = getc(inFILE);
  1602. X                goto next;
  1603. X            } else if (ISEOF(c)) {
  1604. X                newLine = TRUE;
  1605. X                return NULL;
  1606. X            }
  1607. X        }
  1608. X
  1609. X    case '\n':
  1610. X        newLine = TRUE;
  1611. X        goto top;
  1612. X
  1613. X    default:
  1614. X        if (ISEOF(c)) {
  1615. X            newLine = TRUE;
  1616. X            return NULL;
  1617. X        }
  1618. X    name:
  1619. X        id = idBuf;
  1620. X        *id++ = c;
  1621. X        if (ISID1ST(c)) {
  1622. X            *flagP = IDN_NAME;
  1623. X            while (ISIDREST(c = getc(inFILE)))
  1624. X                *id++ = c;
  1625. X        } else if (ISDIGIT(c)) {
  1626. X            *flagP = IDN_NUMBER;
  1627. X            while (ISNUMBER(c = getc(inFILE)))
  1628. X                *id++ = c;
  1629. X        } else
  1630. X            fprintf(stderr, "junk: `\\%3o'", c);
  1631. X        ungetc(c, inFILE);
  1632. X        *id = '\0';
  1633. X        *flagP |= IDN_LITERAL;
  1634. X        return idBuf;
  1635. X    }
  1636. X}
  1637. X
  1638. Xstatic void
  1639. XsetCtype(chars, type)
  1640. X    char        *chars;
  1641. X    int        type;
  1642. X{
  1643. X    short        *rct = &idctype[1];
  1644. X
  1645. X    while (*chars)
  1646. X        rct[*chars++] |= type;
  1647. X}
  1648. Xstatic void
  1649. XclrCtype(chars, type)
  1650. X    char        *chars;
  1651. X    int        type;
  1652. X{
  1653. X    short        *rct = &idctype[1];
  1654. X
  1655. X    while (*chars)
  1656. X        rct[*chars++] &= ~type;
  1657. X}
  1658. X
  1659. Xextern char    *MyName;
  1660. Xstatic void
  1661. Xusage(lang)
  1662. X    char        *lang;
  1663. X{
  1664. X    fprintf(stderr, "Usage: %s does not accept %s scanner arguments\n", MyName, lang);
  1665. X    exit(1);
  1666. X}
  1667. Xstatic char *cDocument[] =
  1668. X{
  1669. X"The C scanner arguments take the form -Sc<arg>, where <arg>",
  1670. X"is one of the following: (<cc> denotes one or more characters)",
  1671. X"  (+|-)u . . . . (Do|Don't) strip a leading `_' from ids in strings.",
  1672. X"  -s<cc> . . . . Allow <cc> in string ids.",
  1673. XNULL
  1674. X};
  1675. Xvoid
  1676. XsetCArgs(lang, op, arg)
  1677. X    char        *lang;
  1678. X    int        op;
  1679. X    char        *arg;
  1680. X{
  1681. X    if (op == '?') {
  1682. X        document(cDocument);
  1683. X        return;
  1684. X    }
  1685. X    switch (*arg++)
  1686. X    {
  1687. X    case 'u':
  1688. X        eatUnder = (op == '+');
  1689. X        break;
  1690. X    case 's':
  1691. X        setCtype(arg, SK);
  1692. X        break;
  1693. X    default:
  1694. X        if (lang)
  1695. X            usage(lang);
  1696. X        break;
  1697. X    }
  1698. X}
  1699. SHAR_EOF
  1700. if test 6502 -ne "`wc -c < 'scan-c.c'`"
  1701. then
  1702.     echo shar: error transmitting "'scan-c.c'" '(should have been 6502 characters)'
  1703. fi
  1704. echo shar: extracting "'stoi.c'" '(1883 characters)'
  1705. sed 's/^X//' << \SHAR_EOF > 'stoi.c'
  1706. X/* Copyright (c) 1986, Greg McGary */
  1707. Xstatic char sccsid[] = "@(#)stoi.c    1.1 86/10/09";
  1708. X
  1709. X#include    <radix.h>
  1710. X#include    <ctype.h>
  1711. X
  1712. Xint dtoi();
  1713. Xint otoi();
  1714. Xint radix();
  1715. Xint stoi();
  1716. Xint xtoi();
  1717. X
  1718. X/*
  1719. X    Use the C lexical rules to determine an ascii number's radix.
  1720. X    The radix is returned as a bit map, so that more than one radix
  1721. X    may apply.  In particular, it is impossible to determine the
  1722. X    radix of 0, so return all possibilities.
  1723. X*/
  1724. Xint
  1725. Xradix(name)
  1726. X    register char    *name;
  1727. X{
  1728. X    if (!isdigit(*name))
  1729. X        return 0;
  1730. X    if (*name != '0')
  1731. X        return RADIX_DEC;
  1732. X    name++;
  1733. X    if (*name == 'x' || *name == 'X')
  1734. X        return RADIX_HEX;
  1735. X    while (*name && *name == '0')
  1736. X        name++;
  1737. X    return (RADIX_OCT | ((*name)?0:RADIX_DEC));
  1738. X}
  1739. X
  1740. X/*
  1741. X    Convert an ascii string number to an integer.
  1742. X    Determine the radix before converting.
  1743. X*/
  1744. Xint
  1745. Xstoi(name)
  1746. X    char        *name;
  1747. X{
  1748. X    switch (radix(name))
  1749. X    {
  1750. X    case RADIX_DEC:    return(dtoi(name));
  1751. X    case RADIX_OCT:    return(otoi(&name[1]));
  1752. X    case RADIX_HEX:    return(xtoi(&name[2]));
  1753. X    case RADIX_DEC|RADIX_OCT: return(0);
  1754. X    default:    return(-1);
  1755. X    }
  1756. X}
  1757. X
  1758. X/*
  1759. X    Convert an ascii octal number to an integer.
  1760. X*/
  1761. Xint
  1762. Xotoi(name)
  1763. X    char        *name;
  1764. X{
  1765. X    register int    n = 0;
  1766. X
  1767. X    while (*name >= '0' && *name <= '7') {
  1768. X        n *= 010;
  1769. X        n += *name++ - '0';
  1770. X    }
  1771. X    if (*name == 'l' || *name == 'L')
  1772. X        name++;
  1773. X    return (*name ? -1 : n);
  1774. X}
  1775. X
  1776. X/*
  1777. X    Convert an ascii decimal number to an integer.
  1778. X*/
  1779. Xint
  1780. Xdtoi(name)
  1781. X    char        *name;
  1782. X{
  1783. X    register int    n = 0;
  1784. X
  1785. X    while (isdigit(*name)) {
  1786. X        n *= 10;
  1787. X        n += *name++ - '0';
  1788. X    }
  1789. X    if (*name == 'l' || *name == 'L')
  1790. X        name++;
  1791. X    return (*name ? -1 : n);
  1792. X}
  1793. X
  1794. X/*
  1795. X    Convert an ascii hex number to an integer.
  1796. X*/
  1797. Xint
  1798. Xxtoi(name)
  1799. X    char        *name;
  1800. X{
  1801. X    register int    n = 0;
  1802. X
  1803. X    while (isxdigit(*name)) {
  1804. X        n *= 0x10;
  1805. X        if (isdigit(*name))
  1806. X            n += *name++ - '0';
  1807. X        else if (islower(*name))
  1808. X            n += 0xa + *name++ - 'a';
  1809. X        else
  1810. X            n += 0xA + *name++ - 'A';
  1811. X    }
  1812. X    if (*name == 'l' || *name == 'L')
  1813. X        name++;
  1814. X    return (*name ? -1 : n);
  1815. X}
  1816. SHAR_EOF
  1817. if test 1883 -ne "`wc -c < 'stoi.c'`"
  1818. then
  1819.     echo shar: error transmitting "'stoi.c'" '(should have been 1883 characters)'
  1820. fi
  1821. echo shar: extracting "'tty.c'" '(1114 characters)'
  1822. sed 's/^X//' << \SHAR_EOF > 'tty.c'
  1823. X#ifdef TERMIO
  1824. X#include    <sys/termio.h>
  1825. X
  1826. Xstruct termio linemode, charmode, savemode;
  1827. X
  1828. Xsavetty()
  1829. X{
  1830. X    ioctl(0, TCGETA, &savemode);
  1831. X    charmode = linemode = savemode;
  1832. X
  1833. X    charmode.c_lflag &= ~(ECHO|ICANON|ISIG);
  1834. X    charmode.c_cc[VMIN] = 1;
  1835. X    charmode.c_cc[VTIME] = 0;
  1836. X
  1837. X    linemode.c_lflag |= (ECHO|ICANON|ISIG);
  1838. X    linemode.c_cc[VEOF] = 'd'&037;
  1839. X    linemode.c_cc[VEOL] = 0377;
  1840. X}
  1841. X
  1842. Xrestoretty()
  1843. X{
  1844. X    ioctl(0, TCSETA, &savemode);
  1845. X}
  1846. X
  1847. Xlinetty()
  1848. X{
  1849. X    ioctl(0, TCSETA, &linemode);
  1850. X}
  1851. X
  1852. Xchartty()
  1853. X{
  1854. X    ioctl(0, TCSETA, &charmode);
  1855. X}
  1856. X
  1857. X#else
  1858. X#include    <sgtty.h>
  1859. X
  1860. Xstruct sgttyb linemode, charmode, savemode;
  1861. X
  1862. Xsavetty()
  1863. X{
  1864. X#ifdef TIOCGETP
  1865. X    ioctl(0, TIOCGETP, &savemode);
  1866. X#else
  1867. X    gtty(0, &savemode);
  1868. X#endif
  1869. X    charmode = linemode = savemode;
  1870. X
  1871. X    charmode.sg_flags &= ~ECHO;
  1872. X    charmode.sg_flags |= RAW;
  1873. X
  1874. X    linemode.sg_flags |= ECHO;
  1875. X    linemode.sg_flags &= ~RAW;
  1876. X}
  1877. X
  1878. Xrestoretty()
  1879. X{
  1880. X#ifdef TIOCSETP
  1881. X    ioctl(0, TIOCSETP, &savemode);
  1882. X#else
  1883. X    stty(0, &savemode);
  1884. X#endif
  1885. X}
  1886. X
  1887. Xlinetty()
  1888. X{
  1889. X#ifdef TIOCSETP
  1890. X    ioctl(0, TIOCSETP, &linemode);
  1891. X#else
  1892. X    stty(0, &savemode);
  1893. X#endif
  1894. X}
  1895. X
  1896. Xchartty()
  1897. X{
  1898. X#ifdef TIOCSETP
  1899. X    ioctl(0, TIOCSETP, &charmode);
  1900. X#else
  1901. X    stty(0, &savemode);
  1902. X#endif
  1903. X}
  1904. X#endif
  1905. SHAR_EOF
  1906. if test 1114 -ne "`wc -c < 'tty.c'`"
  1907. then
  1908.     echo shar: error transmitting "'tty.c'" '(should have been 1114 characters)'
  1909. fi
  1910. echo shar: extracting "'uerror.c'" '(586 characters)'
  1911. sed 's/^X//' << \SHAR_EOF > 'uerror.c'
  1912. X/* Copyright (c) 1986, Greg McGary */
  1913. Xstatic char sccsid[] = "@(#)uerror.c    1.1 86/10/09";
  1914. X
  1915. X#include    <stdio.h>
  1916. X
  1917. Xchar *uerror();
  1918. Xvoid filerr();
  1919. X
  1920. Xextern int    errno;
  1921. Xextern int    sys_nerr;
  1922. Xextern char    *sys_errlist[];
  1923. Xextern char    *MyName;
  1924. X
  1925. Xchar    cannot[] = "%s: Cannot %s `%s' (%s)\n";
  1926. X
  1927. Xchar *
  1928. Xuerror()
  1929. X{
  1930. X    static char    errbuf[10];
  1931. X
  1932. X    if (errno == 0 || errno >= sys_nerr) {
  1933. X        sprintf(errbuf, "error %d", errno);
  1934. X        return(errbuf);
  1935. X    }
  1936. X    return(sys_errlist[errno]);
  1937. X}
  1938. X
  1939. Xvoid
  1940. Xfilerr(syscall, fileName)
  1941. X    char        *syscall;
  1942. X    char        *fileName;
  1943. X{
  1944. X    fprintf(stderr, cannot, MyName, syscall, fileName, uerror());
  1945. X}
  1946. SHAR_EOF
  1947. if test 586 -ne "`wc -c < 'uerror.c'`"
  1948. then
  1949.     echo shar: error transmitting "'uerror.c'" '(should have been 586 characters)'
  1950. fi
  1951. echo shar: extracting "'wmatch.c'" '(830 characters)'
  1952. sed 's/^X//' << \SHAR_EOF > 'wmatch.c'
  1953. X/* Copyright (c) 1986, Greg McGary */
  1954. Xstatic char sccsid[] = "@(#)wmatch.c    1.1 86/10/09";
  1955. X
  1956. X#include    <bool.h>
  1957. X#include    <ctype.h>
  1958. X
  1959. Xbool wordMatch();
  1960. X
  1961. X/*
  1962. X    Does `name' occur in `line' delimited by non-alphanumerics??
  1963. X*/
  1964. Xbool
  1965. XwordMatch(name0, line)
  1966. X    char        *name0;
  1967. X    register char    *line;
  1968. X{
  1969. X    register char    *name = name0;
  1970. X#define IS_ALNUM(c)    (isalnum(c) || (c) == '_')
  1971. X
  1972. X    for (;;) {
  1973. X        /* find an initial-character match */
  1974. X        while (*line != *name) {
  1975. X            if (*line == '\n')
  1976. X                return FALSE;
  1977. X            line++;
  1978. X        }
  1979. X        /* do we have a word delimiter on the left ?? */
  1980. X        if (IS_ALNUM(line[-1])) {
  1981. X            line++;
  1982. X            continue;
  1983. X        }
  1984. X        /* march down both strings as long as we match */
  1985. X        while (*++name == *++line)
  1986. X            ;
  1987. X        /* is this the end of `name', is there a word delimiter ?? */
  1988. X        if (*name == '\0' && !IS_ALNUM(*line))
  1989. X            return TRUE;
  1990. X        name = name0;
  1991. X    }
  1992. X}
  1993. SHAR_EOF
  1994. if test 830 -ne "`wc -c < 'wmatch.c'`"
  1995. then
  1996.     echo shar: error transmitting "'wmatch.c'" '(should have been 830 characters)'
  1997. fi
  1998. #    End of shell archive
  1999. exit 0
  2000.